/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package manejadores;

import com.akcess.exception.*;
import com.akcess.vo.*;
import com.akcess.impl.*;
import com.akcess.dao.*;
import java.sql.*;
import java.util.*;

/**
 *Esta clase se utiliza para realizar las tareas relacionadas con la gestion de las Reservas de los recursos,
 * como creacion, cancelado y modificacion de Reservas, entre otras cosas.
 * @author Alejandro y R2
 */
public class ManejadorReservas {
private String mensajeProblema=null;

    private Connection conexion = null;

    /**
     * Constructor de la Clase ManejadorReservas que recibe una conexion a la BD.
     * @param con Conexion a la BD, el cual se utilizara como el unico atributo de esta clase. (Connection conexion)
     */
    public ManejadorReservas(Connection con) {
        this.conexion = con;
    }
    /**
     * Agrega una reserva en la BD y captura la excepcion en el caso de que 
     * la reserva se SOLAPE con otra o si las horas y las fechas son inconsistentes,
     * o sea que la fecha de reserva sea mayor o igual a la fecha de creacion de la reserva.
     * Y que la hora de inicio de reserva sea mayor a la hora fin de reserva. 
     * Al capturar la excepcion guarda el mensaje que causo la NO insercion en la base de datos.
     * Hay dos tipos de inserciones: 1) Cuando la reserva tiene una ubicacion, que es en el caso que se reserve un recurso movil.
     * 2) En el caso que la reserva no tenga una ubicacion que es en el caso que se reserve un aula o una sala de maquina.
     * @param reservita Es un objeto que contiene todos los datos necesarios para agregar a la base de datos. El objeto reserva puede o no tener una ubicacion eso depende del recurso que se quiere reservar.
     * @return Retorna TRUE si la reserva fue insertada correctamente, y false si la reserva no pudo ser insertada. Si la reserva no pudo ser insertada se captura el mensaje de excepcion y se guarda en una variable de la clase. Que luego puede ser consultado.
     */
    
    public boolean AgregarReserva( Reserva reservita ){
        ReservaDAOImpl manejarReservas= new ReservaDAOImpl();
        try {
            if(reservita.getId_ubicacion()!=0){
               //Si es distinto de 0, entonces tiene ubicacion. La ubicacion 0 NO existe!
               manejarReservas.insert(reservita, this.conexion);
               return true; 
            }else
            {
               //Si es igual a 0, entonces NO tiene ubicacion. 
               manejarReservas.insertSinUbicacion(reservita, this.conexion);
               return true; 
            }
            
        } catch (ReservaException ex) {
            this.mensajeProblema=ex.getCausa();
            return false;
        }
        
    }
    
    /**
     * Agrega una reserva en la BD y captura la excepcion en el caso de que 
     * la reserva se SOLAPE con otra o si las horas y las fechas son inconsistentes,
     * o sea que la fecha de reserva sea mayor o igual a la fecha de creacion de la reserva.
     * Y que la hora de inicio de reserva sea mayor a la hora fin de reserva. 
     * Al capturar la excepcion guarda el mensaje que causo la NO insercion en la
     * @param reservita
     * @return Retorna TRUE si la reserva fue insertada correctamente, y false si la reserva no pudo ser insertada.
     */
    
    public boolean ModificarReserva(  Reserva reservita, int idReserva ){
        ReservaDAOImpl manejarReservas= new ReservaDAOImpl();
        ReservaPK reservPK=new ReservaPK();
        reservPK.setId_reserva(idReserva);
        try {
            if(reservita.getId_ubicacion()!=0){
               //Si es distinto de 0, entonces tiene ubicacion. La ubicacion 0 NO existe!
               manejarReservas.update(reservPK,reservita, this.conexion);
               return true; 
            }else
            {
               //Si es igual a 0, entonces NO tiene ubicacion. 
               manejarReservas.updateSinUbi(reservPK,reservita, this.conexion);
               return true; 
            }
            
        } catch (ReservaException ex) {
            this.mensajeProblema=ex.getCausa();
            return false;
        }
        
    }
    /**
     * Recupera un String con un mensaje de la causa del problema al insertar una nueva reserva o al modificar una existente.
     * @return Un String que contiene el mensaje con la causa del problema y si NO hay problema retorna NULL
     */
    public String getMensajeProblem()
    {
        return this.mensajeProblema;
    }
    
    
    /**
     * Realiza las modificaciones en la BD que fueron realizadas sobre un Recurso de Aula determinado, realizando las modificaciones
     * en las Tablas Recurso y Aulas.
     * @param recurso Representa el Recurso en la tabla Recurso que fue modificado.     
     * @param aula Representa el aula en la tabla Aulas que fue modificado.
     * @throws com.akcess.exception.AulasException Lanza excepciones del tipo AulasException, creada por el DAOGenerator.
     */
    public void ModificarRecursoAula(Recurso recurso, Aulas aula) throws AulasException {
        try {
            //Modificaciones en la tabla Aulas.
            AulasDAOImpl manejadorAulas = new AulasDAOImpl();
            AulasPK aulasPK = new AulasPK();
            aulasPK.setId_recurso(recurso.getId_recurso());
            manejadorAulas.update(aulasPK, aula, this.conexion);

//Modificaciones en la tabla Recurso.
            RecursoDAOImpl manejadorRecurso = new RecursoDAOImpl();
            RecursoPK recursoPK = new RecursoPK();
            recursoPK.setId_recurso(recurso.getId_recurso());
            Recurso recursoOriginal = manejadorRecurso.findByPrimaryKey(recursoPK, this.conexion);
            recurso.setBorrado(recursoOriginal.getBorrado());
            recurso.setFechacreacion(recursoOriginal.getFechacreacion());
            manejadorRecurso.update(recursoPK, recurso, this.conexion);

        } catch (AulasException ex) {
            ex.printStackTrace();
        } catch (RecursoException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Obtiene todos los Recursos de tipo Aulas existentes en la BD.
     * @return Un vector de tipo RecursoAulaCompleto, que contiene toda la informacion de cada Recurso de tipo Aulas.
     * @throws com.akcess.exception.AulasException Lanza excepciones del tipo Recurso_humanoException, creada por el DAOGenerator.
     */
    public RecursoAulaCompleto[] ListarRecursosAulas() throws AulasException {
        RecursoAulaCompleto[] recursos = null;
        try {
            AulasDAOImpl recursoDAO = new AulasDAOImpl();
            recursos = recursoDAO.ObtenerRecursoCompleto(this.conexion);
        } catch (AulasException ex) {
            ex.printStackTrace();
        }
        return recursos;
    }

    /**
     * Realiza la cancelacion en la BD de una Reserva determinada.
     * @param idReserva Contiene el id de la Reserva que sera eliminado o borrado logicamente.
     * @throws com.akcess.exception.ReservaException Lanza excepciones del tipo ReservaException, creada por el DAOGenerator.
     */
    public void CancelarReserva(int idReserva, int idOperador) throws ReservaException {
        ReservaPK reservaPK = new ReservaPK();
        reservaPK.setId_reserva(idReserva);
        ReservaDAOImpl manejadorReserva = new ReservaDAOImpl();
        Reserva reserva = manejadorReserva.findByPrimaryKey(reservaPK, this.conexion);
        reserva.setCancelada(true);   
        reserva.setId_operador(idOperador);
        manejadorReserva.updateSinUbi(reservaPK, reserva, this.conexion);
    }

    /**
     * Obtiene de la BD un Recurso de tipo Aulas determinado por un id de recurso.
     * @return El Recurso de tipo Aulas especificado por idRecurso.
     * @param idRecurso Contiene el id del Recurso que debera ser buscado.
     * @throws com.akcess.exception.AulasException Lanza excepciones del tipo AulasException, creada por el DAOGenerator.
     */
    public RecursoAulaCompleto ObtenerRecursoAula(int idRecurso) throws AulasException {
        //Me conecto a la BD                   
        AulasDAOImpl manejadorRecurso = new AulasDAOImpl();
        RecursoAulaCompleto recurso = manejadorRecurso.EncontrarRecursoCompleto(idRecurso, this.conexion);
        return recurso;
    }

    /**
     * Retorna todas la Reservas que se realizaron sobre alguna Aula del sistema.
     * @return Un vector de tipo Aulas que contiene todas las reservas.
     * @throws com.akcess.exception.ReservaException Lanza excepciones del tipo ReservaException, creada por el DAOGenerator.
     */
    public Aulas[] ObtenerReservasAulas() throws ReservaException {
        try {
            ReservaDAOImpl Manager = new ReservaDAOImpl();
            Aulas[] aulas = Manager.ObtenerReservasAulas(this.conexion);
            return aulas;

        } catch (ReservaException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * Retorna todas la Reservas que se realizaron sobre alguna Sala de maquinas del sistema.
     * @return Un vector de tipo Sala_de_maquinas que contiene todas las reservas.
     * @throws com.akcess.exception.ReservaException Lanza excepciones del tipo ReservaException, creada por el DAOGenerator.
     */
    public Sala_de_maquinas[] ObtenerReservasSalas() throws ReservaException {
        try {
            ReservaDAOImpl Manager = new ReservaDAOImpl();
            Sala_de_maquinas[] salas = Manager.ObtenerReservasSalas(this.conexion);
            return salas;

        } catch (ReservaException ex) {
            ex.printStackTrace();
            return null;
        }
    }
    /**
     * Retorna todas la ubicaciones que se tiene en la Base de Datos.
     * @return Un vector de tipo Ubicacion que contiene todas las ubicaciones.
     * @throws com.akcess.exception.UbicacionException Lanza excepciones del tipo UbicacionException, creada por el DAOGenerator.
     */
    public Ubicacion[] ObtenerUbicaciones() throws UbicacionException {
        try {
            UbicacionDAOImpl ManagerUbi = new UbicacionDAOImpl();
            Ubicacion[] ubicaciones = ManagerUbi.findAll(this.conexion);
            return ubicaciones;
        } catch (UbicacionException ex) {
            ex.printStackTrace();
            return null;
        }
    }
    
    /**
     * Retorna todas la Reservas que se realizaron sobre algun Recurso Movil del sistema.
     * @return Un vector de tipo Recurso_movil que contiene todas las reservas.
     * @throws com.akcess.exception.ReservaException Lanza excepciones del tipo ReservaException, creada por el DAOGenerator.
     */
    public Recurso_movil[] ObtenerReservasRM (int idTipo) throws ReservaException {
        try {
            ReservaDAOImpl Manager = new ReservaDAOImpl();
            Recurso_movil[] RM = Manager.ObtenerReservasRM(idTipo,this.conexion);
            return RM;

        } catch (ReservaException ex) {
            ex.printStackTrace();
            return null;
        }
    }
    
    /**
     * Retorna la Reserva de un Aula, que se especifica mediante el parametro recibido.
     * @return Un objeto de tipo RecursoAulaCompleto.
     * @throws com.akcess.exception.ReservaException Lanza excepciones del tipo ReservaException, creada por el DAOGenerator.
     */
    public RecursoAulaCompleto ObtenerReservaAula(int idReserva) throws ReservaException {
        try {
            ReservaDAOImpl Manager = new ReservaDAOImpl();
            RecursoAulaCompleto aula = Manager.ObtenerReservaAula(idReserva,this.conexion);
            return aula;

        } catch (ReservaException ex) {
            ex.printStackTrace();
            return null;
        }
    }
    
    /**
     * Retorna la Reserva de una Sala, que se especifica mediante el parametro recibido.
     * @return Un objeto de tipo RecursoSMCompleto.
     * @throws com.akcess.exception.ReservaException Lanza excepciones del tipo ReservaException, creada por el DAOGenerator.
     */
    public RecursoSMCompleto ObtenerReservaSM(int idReserva) throws ReservaException {
        try {
            ReservaDAOImpl Manager = new ReservaDAOImpl();
            RecursoSMCompleto sala = Manager.ObtenerReservaSM(idReserva,this.conexion);
            return sala;

        } catch (ReservaException ex) {
            ex.printStackTrace();
            return null;
        }
    }
    
    /**
     * Retorna la Reserva de un Recurso Movil, que se especifica mediante el parametro recibido.
     * @return Un objeto de tipo Recurso_movil.
     * @throws com.akcess.exception.ReservaException Lanza excepciones del tipo ReservaException, creada por el DAOGenerator.
     */
    public Recurso_movil ObtenerReservaRM(int tipoRecurso, int idReserva) throws ReservaException {
        try {
            ReservaDAOImpl Manager = new ReservaDAOImpl();
            Recurso_movil recurso = Manager.ObtenerReservaRM(tipoRecurso, idReserva, this.conexion);
            return recurso;

        } catch (ReservaException ex) {
            ex.printStackTrace();
            return null;
        }
    }
    
    /**
     * Registra un evento para una reserva especifica, es decir añade una fila a la Tabla Registro_evento.
     * @param Registro_evento Viene a ser el nuevo Evento que sera insertado a la BD para una determinada Reserva.
     * @throws com.akcess.exception.Registro_eventoException Lanza excepciones del tipo Tiene_encargadosException, creada por el DAOGenerator.
     */
    public void RegistrarEvento(Registro_evento evento) throws Registro_eventoException, EventoException, ReservaException, RecursoException{
     
             //Agrego a la base de datos el nuevo Evento, es decir el nuevo registro.
            Registro_eventoDAOImpl manejador = new Registro_eventoDAOImpl();
            manejador.insert(evento, this.conexion);
            
            //Ahora veo si el evento hace que el recurso estee disponible o no.
            //Primero obtengo el evento
             EventoDAOImpl manejadorEvento = new EventoDAOImpl();
             Evento event = manejadorEvento.findByPrimaryKey(evento.getId_evento(), this.conexion);
             
             //Luego obtengo la reserva para saber cual recurso modificar.
             ReservaDAOImpl manejadorReserva = new ReservaDAOImpl();
             Reserva reserva = manejadorReserva.findByPrimaryKey((int)evento.getId_reserva(), this.conexion);
             
             //Ahora obtengo el recurso a modificar.
             RecursoDAOImpl manejadorRecurso = new RecursoDAOImpl();
             Recurso recurso = manejadorRecurso.findByPrimaryKey(reserva.getId_recurso(), this.conexion);
             RecursoPK recursopk = new RecursoPK(recurso.getId_recurso());
             if(event.getAfectaRecurso()){
                 recurso.setDisponible(false);
                 manejadorRecurso.update(recursopk, recurso, this.conexion);
             }else{
                 recurso.setDisponible(true);
                 manejadorRecurso.update(recursopk, recurso, this.conexion);
             }
       
    }
    
    /**
     * Obtiene todos los eventos que se realizan sobre una Reserva determinada.
     * @param idReserva Nos indica el id de la reserva cuyos eventos queremos obtener.
     * @return  Retorna un arreglo de tipo Evento, conteniendo todos los eventos que ocurren en la reserva.
     * @throws com.akcess.exception.Registro_eventoException Lanza excepciones del tipo Tiene_encargadosException, creada por el DAOGenerator.
     */
    public Evento[] ObtenerEventos(int idReserva) throws Registro_eventoException{
     
             //Agrego a la base de datos el nuevo SO
            Registro_eventoDAOImpl manejador = new Registro_eventoDAOImpl();
            Evento [] eventos = manejador.ObtenerEventos( idReserva, this.conexion);
            return eventos;
       
    }
    
}
